package com.hxd.qzg.module;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import com.hxd.qzg.common.BaseController;
import com.hxd.qzg.common.Operation;
import com.hxd.qzg.common.Result;
import com.hxd.qzg.common.SbhFactory;
import com.hxd.qzg.common.ServiceException;
import com.hxd.qzg.common.UseBox;
import com.hxd.qzg.common.enums.MsgTypeEnum;
import com.hxd.qzg.common.model.Img;
import com.hxd.qzg.common.vo.BoxGroupVO;
import com.hxd.qzg.common.vo.BoxListVO;
import com.hxd.qzg.common.vo.BoxVO;
import com.hxd.qzg.common.vo.CertificateVO;
import com.hxd.qzg.common.vo.PayInfoVO;
import com.hxd.qzg.websocket.WebSocket;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.upload.UploadFile;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;


/**
 * @author YanJiaXing
 * @date 2017/11/5
 */
public class ApiController extends BaseController {

    private static final Log logger = LogFactory.get();

	@Inject
	BoxGroupService boxGroupService;
	@Inject
	UseBox useBox;

	Prop CONFIG_PROP = PropKit.use("config.properties");

	/**
	 * 显示分组信息
	 */

	public void login() {
		String userName = get("userName");
		if (StringUtils.isEmpty(userName)) {
			throw new ServiceException("用户名不能空");
		}
		String pwd = get("pwd");

		if (StringUtils.isEmpty(pwd)) {
			throw new ServiceException("密码不能为空");
		}
		Record record = Db.findFirst("SELECT * FROM api_user WHERE is_delete=0 AND username =? ", userName);
		if (null == record) {
			throw new ServiceException("此账户不存在");
		}
		String pwdStr = record.getStr("pwd");
		if (!pwd.equals(pwdStr)) {
			throw new ServiceException("密码不正确");
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", record.get("id"));
		map.put("usernmae", record.get("username"));
		map.put("realName", record.get("real_name"));
		map.put("token", java.util.UUID.randomUUID());
		renderJson(Result.success(map));
	}

	/**
	 * 显示分组信息
	 */

	public void list() {
		List<BoxGroupVO> boxGroups = boxGroupService.listBoxGroup();
		renderJson(Result.success(boxGroups));
	}


	/**
	 * 根据分组id 显示当前分组 count
	 */
	public void listBox() {
		String boxGroupIdStr = get("boxGroupId");
		Integer boxGroupId = 0;
		if (StringUtils.isEmpty(boxGroupIdStr)) {
			String sbh = get("sbh");
			if (StringUtils.isNotEmpty(sbh)) {
				boxGroupId = SbhFactory.getBoxGroupId(sbh);
			}
		} else {
			boxGroupId = Integer.valueOf(boxGroupIdStr);
		}
		BoxListVO box = boxGroupService.list(boxGroupId);
		renderJson(Result.success(box));
	}

	/**
	 * 根据柜子id 进入 查看当前内柜子信息
	 */
	public void getBoxInfo() {
		String boxIdStr = get("boxId");
		if (StringUtils.isEmpty(boxIdStr)) {
			throw new ServiceException("boxId 不能为空");
		}
		Integer boxId = Integer.valueOf(boxIdStr);
		BoxVO cabinetVO = boxGroupService.getBoxInfo(boxId);
		renderJson(Result.success(cabinetVO));
	}

	/**
	 * 扫描
	 * 
	 */
	public void scan() {


		String scanInfo = get("scanInfo");
		if (StringUtils.isEmpty(scanInfo)) {
			throw new ServiceException("scanInfo 不能为空");
		}

		List<CertificateVO> certificateVOs = boxGroupService.scan(1, scanInfo);
		renderJson(Result.success(certificateVOs));
	}

	/**
	 * 仅仅打开柜子不更改信息
	 * 
	 */
	public void openBox() {

		String boxIdStr = get("boxId");
		if (StringUtils.isEmpty(boxIdStr)) {
			throw new ServiceException("boxId 不能为空");
		}
		String idCard = get("idCard");

		String userId = get("userId");

		if (StringUtils.isEmpty(userId) && StringUtils.isEmpty(idCard)) {
			throw new ServiceException("idCard 或者 userId 不能同时为空");
		}

		String name = get("name");
		String sbh = get("sbh");
		Operation operation = new Operation();
		operation.setBoxId(boxIdStr);
		operation.setUserId(userId);
		operation.setSbh(sbh);
		operation.setIdcard(idCard);
		operation.setName(name);
		this.checkOperation(operation, MsgTypeEnum.OPEN.getCode());
		renderJson(Result.success());
	}

	@Clear
	private void checkOperation(Operation operation, Integer code) {
		boxGroupService.handle(operation, code);
	}
	/**
	 * 打开柜子取出证件
	 * 
	 */
	public void takeOutCertificate() {
		String boxIdStr = get("boxId");
		if (StringUtils.isEmpty(boxIdStr)) {
			throw new ServiceException("boxId 不能为空");
		}

		String idCard = get("idCard");

		String name = get("name");

		String sbh = get("sbh");

		String userId = get("userId");

		Operation operation = new Operation();
		operation.setBoxId(boxIdStr);
		operation.setUserId(userId);
		operation.setSbh(sbh);
		operation.setIdcard(idCard);
		operation.setName(name);
		this.checkOperation(operation, MsgTypeEnum.QZ.getCode());
		renderJson(Result.success());
	}


	/**
	 * 确定扫描向信息
	 * 
	 */
	public void scanSave() {
		String boxIdStr = get("boxId");
		if (StringUtils.isEmpty(boxIdStr)) {
			throw new ServiceException("boxId 不能为空");
		}

		
		String scanInfo = get("scanInfo");
		if (StringUtils.isEmpty(scanInfo)) {
			throw new ServiceException("scanInfo 不能为空");
		}
		String idCard = get("idCard");

		String name = get("name");

		String sbh = get("sbh");

		String userId = get("userId");
		Operation operation = new Operation();
		operation.setBoxId(boxIdStr);
		operation.setUserId(userId);
		operation.setSbh(sbh);
		operation.setIdcard(idCard);
		operation.setName(name);
		this.checkOperation(operation, MsgTypeEnum.SCAN.getCode());
		renderJson(Result.success());
	}

	/**
	 * 验证客户支付信息
	 * 
	 */
	public void isPay() {
		String scanInfo = get("scanInfo");
		if (StringUtils.isEmpty(scanInfo)) {
			throw new ServiceException("scanInfo 不能为空");
		}
		boxGroupService.isPay(scanInfo);
		renderJson(Result.success());
	}

	/**
	 * 创建二维码
	 * 
	 */
	public void qRCode() {

		String scanInfo = get("scanInfo");
		if (StringUtils.isEmpty(scanInfo)) {
			throw new ServiceException("scanInfo 不能为空");
		}
		Integer type = getInt("type");
		PayInfoVO payInfoVO = boxGroupService.qRCode(scanInfo, type);
		renderJson(Result.success(payInfoVO));
	}

	/**
	 * 客户打开柜子
	 * 
	 */
	public void customerOpenBox() {
		String scanInfo = get("scanInfo");
		if (StringUtils.isEmpty(scanInfo)) {
			throw new ServiceException("scanInfo 不能为空");
		}
		String idCard = get("idCard");

		String name = get("name");

		String sbh = get("sbh");

		String userId = get("userId");

		Operation operation = new Operation();
		operation.setUserId(userId);
		operation.setSbh(sbh);
		operation.setIdcard(idCard);
		operation.setName(name);
		operation.setScanInfo(scanInfo);
		renderJson(Result.success());
	}


	/**
	 * 关闭box
	 * 
	 */
	public void closeBox() {
		String ban = get("ban");
		if (StringUtils.isEmpty(ban)) {
			throw new ServiceException("ban 不能为空");
		}

		String boxNo = get("boxNo");
		if (StringUtils.isEmpty(ban)) {
			throw new ServiceException("boxNo 不能为空");
		}


		try {
			new WebSocket().onCloseMessage(ban, boxNo);
		} catch (IOException e) {
			throw new ServiceException("通知 失败");
		}
		renderJson(Result.success());
	}

	public void baseUpload() {

		String path = CONFIG_PROP.get("upload.path");
		UploadFile file = null;
		Long imageId = 0L;
		String filePath = "";
		try {
			file = getFile("image");
			// 重新换名称

			String date = DateUtil.format(new Date(), "yyyy-MM-dd");
			filePath = path + "//" + date;
			File dir = new File(filePath);
			if (!dir.exists()) {
				dir.mkdirs();
			}
			imageId = IdUtil.getSnowflake(0, 0).nextId();
			filePath = filePath + "//" + imageId;
			file.getFile().renameTo(new File(filePath));
			logger.info("path {} ", path);
			logger.info("filePath {} ", filePath);
			logger.info("fileName {}", file.getFileName());
		} catch (Exception exception) {
			throw new ServiceException("上传失败");
		}

		String idCard = get("idCard");
		if (StringUtils.isEmpty(idCard)) {
			throw new ServiceException("idCard 不能为空");
		}
		if (!IdcardUtil.isValidCard(idCard)) {
			throw new ServiceException("idCard错误");
		}
		logger.info("idCard {} ", idCard);
		String name = get("name");
		if (StringUtils.isEmpty(name)) {
			throw new ServiceException("name 不能为空");
		}
		logger.info("name {} ", name);
		String timestamp = get("timestamp");
		logger.info("timestamp {} ", timestamp);
		String scanInfo = get("scanInfo");
		if (StringUtils.isEmpty(scanInfo)) {
			throw new ServiceException("scanInfo 不能为空");
		}
		String sbh = get("sbh");

		// 存储记录
		this.save(filePath, timestamp, name, idCard, imageId, scanInfo, sbh);

		try {
			file.getFile().delete();
		} catch (Exception e) {
			logger.info("之前的file 删除异常,不影响流程 {} ", file.getFileName());
		}
		renderJson(Result.success());
	}

	@Clear
	private void save(String filePath, String timestamp, String name, String idCard, Long imageId, String scanInfo,
			String sbh) {
		Img img = new Img();
		img.setPath(filePath);
		img.setImgTimestamp(Integer.valueOf(timestamp));
		img.setName(name);
		img.setDateNow(new Date());
		img.setIdCard(idCard);
		img.setImgId(imageId.toString());
		img.setScanInfo(scanInfo);
		img.setSbh(sbh);
		String url = SbhFactory.getImgUrl();
		img.setUri(url + imageId);
		boolean bl = img.save();
		if (!bl) {
			throw new ServiceException("img 数据保存失败");
		}
	}
	public void getImg() {
		String fileName = get("fileName");
		if (StringUtils.isEmpty(fileName)) {
			throw new ServiceException("fileName 不能为空");
		}
		Record record = Db.findFirst("SELECT * FROM api_img WHERE img_id=?", fileName);
		if (null == record) {
			throw new ServiceException("图标被删除");
		}
		// 取路径
		logger.info("图片名称  {}  ", fileName);

		FileInputStream fis = null;
		OutputStream os = null;
		HttpServletResponse response = getResponse();
		response.setContentType("image/jpeg; charset=GBK");
		try {

			String filePath = record.getStr("path");
			logger.info("图片filePath  {}  ", filePath);
			fis = new FileInputStream(filePath);
			os = response.getOutputStream();
			int count = 0;
			byte[] buffer = new byte[1024 * 8];
			while ((count = fis.read(buffer)) != -1) {
				os.write(buffer, 0, count);
				os.flush();
			}
		} catch (Exception e) {
			logger.info("图片无法访问 可能已经删除 ", fileName);
		}
		try {
			fis.close();
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		renderNull();
	}

}